home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / Synthesizer Source / Synthesizer Folder / WaveTableOscControl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  66.1 KB  |  1,761 lines  |  [TEXT/KAHL]

  1. /* WaveTableOscControl.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Synthesizer:  Digital Music Synthesis on General Purpose Computers     */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "WaveTableOscControl.h"
  31. #include "FastFixedPoint.h"
  32. #include "Memory.h"
  33. #include "EnvelopeState.h"
  34. #include "SampleConsts.h"
  35. #include "LFOGenerator.h"
  36. #include "Multisampler.h"
  37. #include "OscillatorSpecifier.h"
  38. #include "Envelope.h"
  39. #include "LFOListSpecifier.h"
  40. #include "FastModulation.h"
  41. #include "64BitMath.h"
  42. #include "ErrorDaemon.h"
  43.  
  44.  
  45. /* prototypes for fast playback routines */
  46. static void                        Wave_Mono_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  47.                                                 long SampleCount, largefixedsigned* RawBuffer);
  48. static void                        Wave_Stereo_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  49.                                                 long SampleCount, largefixedsigned* RawBuffer);
  50. static void                        Wave_Mono_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  51.                                                 long SampleCount, largefixedsigned* RawBuffer);
  52. static void                        Wave_Stereo_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  53.                                                 long SampleCount, largefixedsigned* RawBuffer);
  54.  
  55. static void                        Wave_Mono_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  56.                                                 long SampleCount, largefixedsigned* RawBuffer);
  57. static void                        Wave_Stereo_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  58.                                                 long SampleCount, largefixedsigned* RawBuffer);
  59. static void                        Wave_Mono_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  60.                                                 long SampleCount, largefixedsigned* RawBuffer);
  61. static void                        Wave_Stereo_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  62.                                                 long SampleCount, largefixedsigned* RawBuffer);
  63.  
  64. static void                        Wave_Mono_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  65.                                                 long SampleCount, largefixedsigned* RawBuffer);
  66. static void                        Wave_Stereo_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  67.                                                 long SampleCount, largefixedsigned* RawBuffer);
  68. static void                        Wave_Mono_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  69.                                                 long SampleCount, largefixedsigned* RawBuffer);
  70. static void                        Wave_Stereo_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  71.                                                 long SampleCount, largefixedsigned* RawBuffer);
  72.  
  73. static void                        Wave_NoOutput(WaveTableStateRec* State,
  74.                                                 long SampleCount, largefixedsigned* RawBuffer);
  75.  
  76.  
  77. /* wave table oscillator template information record */
  78. struct WaveTableTemplateRec
  79.     {
  80.         /* source information for the wave table */
  81.         MultiSampleRec*                WaveTableSourceSelector;
  82.  
  83.         /* sampling rate for final output */
  84.         long                                    FinalOutputSamplingRate;
  85.         /* number of envelope updates per second */
  86.         float                                    EnvelopeTicksPerSecond;
  87.  
  88.         /* values for scaling the frequency of something.  if we were really serious about */
  89.         /* this, we'd traverse all of the oscillators with integral multiples or harmonic */
  90.         /* fractions of the pitch & set their differentials to the same precision as the */
  91.         /* worst oscillator so that they would all stay in sync as time progressed. */
  92.         float                                    FrequencyMultiplier;
  93.  
  94.         /* stereo status */
  95.         NumChannelsType                StereoPlayback;
  96.         /* time interpolation flag */
  97.         MyBoolean                            InterpolateThroughTime;
  98.         /* inter-wave interpolation flag */
  99.         MyBoolean                            InterpolateAcrossWaves;
  100.         /* include in final output flag */
  101.         MyBoolean                            IncludeInFinalOutput;
  102.  
  103.         /* envelope templates */
  104.         EnvelopeRec*                    LoudnessEnvelopeTemplate;
  105.         LFOListSpecRec*                LoudnessLFOTemplate;
  106.         EnvelopeRec*                    IndexEnvelopeTemplate;
  107.         LFOListSpecRec*                IndexLFOTemplate;
  108.  
  109.         /* miscellaneous control parameters */
  110.         float                                    StereoBias;
  111.         float                                    TimeDisplacement;
  112.         float                                    OverallOscillatorLoudness;
  113.  
  114.         /* error logging facility */
  115.         ErrorDaemonRec*                ErrorDaemon;
  116.  
  117.         /* link for list control */
  118.         WaveTableTemplateRec*    Next;
  119.     };
  120.  
  121.  
  122. /* wave table oscillator state record */
  123. struct WaveTableStateRec
  124.     {
  125.         /* current sample position into the wave table */
  126.         LongLongRec                        WaveTableSamplePosition; /* 32-bit fixed point */
  127.         /* current increment value for the wave table sample position */
  128.         LongLongRec                        WaveTableSamplePositionDifferential; /* 32-bit fixed point */
  129.  
  130.         /* envelope tick countdown for pre-start time */
  131.         long                                    PreStartCountdown;
  132.  
  133.         /* function for generating a bunch of samples from the wave table */
  134.         void                                    (*WaveTableGenSamples)(WaveTableStateRec* State,
  135.                                                         long SampleCount, largefixedsigned* RawBuffer);
  136.  
  137.         /* number of frames per table */
  138.         long                                    FramesPerTable;
  139.         /* number of tables */
  140.         long                                    NumberOfTables;
  141.         /* raw wave table data array */
  142.         void**                                WaveTableMatrix;
  143.         /* number of bits in the data for the table */
  144.         NumBitsType                        TableNumBits;
  145.  
  146.         /* current index into table of waves.  0 = lowest wave table, NumberOfTables = highest */
  147.         FastFixedType                    WaveTableIndex;
  148.         /* envelope controlling wave table index */
  149.         /* the envelope is TOTALLY responsible for the value of WaveTableIndex */
  150.         EvalEnvelopeRec*            WaveTableIndexEnvelope;
  151.         /* LFO generators modifying the output of the index envelope generator */
  152.         LFOGenRec*                        IndexLFOGenerator;
  153.  
  154.         /* NOTE:  either OverallLoudness or Left/RightLoudness are used, but not both */
  155.         /* current overall loudness for oscillator */
  156.         FastFixedType                    OverallLoudness; /* 15-bit fixed point, 0..1 */
  157.         /* left channel loudness */
  158.         FastFixedType                    LeftLoudness; /* 15-bit fixed point, 0..1 */
  159.         /* right channel loudness */
  160.         FastFixedType                    RightLoudness; /* 15-bit fixed point, 0..1 */
  161.         /* panning position for splitting envelope generator into stereo channels */
  162.         /* 0 = left channel, 0.5 = middle, 1 = right channel */
  163.         FastFixedType                    Panning; /* 15-bit fixed point, -1..1 */
  164.         /* envelope that is generating the loudness information */
  165.         /* the envelope is TOTALLY responsible for the loudness */
  166.         EvalEnvelopeRec*            WaveTableLoudnessEnvelope;
  167.         /* LFO generators modifying the output of the loudness envelope generator */
  168.         LFOGenRec*                        LoudnessLFOGenerator;
  169.  
  170.         /* this flag is True if the wave table data was defined at the specified pitch */
  171.         /* (and the wave table array is thus valid) or False if there is no wave table */
  172.         /* at this pitch (and the array is invalid) */
  173.         MyBoolean                            WaveTableWasDefined;
  174.  
  175.         /* this is only used for modulation:  when modulating, the amplitude of the */
  176.         /* wave for modulation should not be affected by the output volume, but only by */
  177.         /* the envelope controlling modulation.  therefore, for modulation only, the */
  178.         /* loudness envelope does not include the effect of global volume scaling, and */
  179.         /* we use this field to handle that instead. */
  180.         float                                    NoteLoudnessScaling;
  181.  
  182.         /* static information for the wave table */
  183.         WaveTableTemplateRec    Template; /* a copy of the data */
  184.  
  185.         /* this flag is true if we are doing modulation */
  186.         MyBoolean                            DoingModulation;
  187.  
  188.         /* link for list control */
  189.         WaveTableStateRec*        Next;
  190.     };
  191.  
  192.  
  193.  
  194.  
  195. static WaveTableTemplateRec*        WaveTableTemplateFreeList = NIL;
  196. static WaveTableStateRec*                WaveTableStateFreeList = NIL;
  197.  
  198.  
  199. /* get rid of all cached memory for state or template records */
  200. void                                    FlushWaveTableOscControl(void)
  201.     {
  202.         while (WaveTableTemplateFreeList != NIL)
  203.             {
  204.                 WaveTableTemplateRec*        Temp;
  205.  
  206.                 Temp = WaveTableTemplateFreeList;
  207.                 WaveTableTemplateFreeList = WaveTableTemplateFreeList->Next;
  208.                 ReleasePtr((char*)Temp);
  209.             }
  210.  
  211.         while (WaveTableStateFreeList != NIL)
  212.             {
  213.                 WaveTableStateRec*        Temp;
  214.  
  215.                 Temp = WaveTableStateFreeList;
  216.                 WaveTableStateFreeList = WaveTableStateFreeList->Next;
  217.                 ReleasePtr((char*)Temp);
  218.             }
  219.     }
  220.  
  221.  
  222. #if DEBUG
  223. static void                        CheckValidWaveTableTemplate(WaveTableTemplateRec* Object)
  224.     {
  225.         WaveTableTemplateRec*    Scan;
  226.  
  227.         Scan = WaveTableTemplateFreeList;
  228.         while (Scan != NIL)
  229.             {
  230.                 if (Scan == Object)
  231.                     {
  232.                         PRERR(ForceAbort,"CheckValidWaveTableTemplate:  template is on free list");
  233.                     }
  234.                 Scan = Scan->Next;
  235.             }
  236.     }
  237. #else
  238. #define CheckValidWaveTableTemplate(x) ((void)0)
  239. #endif
  240.  
  241.  
  242. #if DEBUG
  243. static void                        CheckValidWaveTableState(WaveTableStateRec* Object)
  244.     {
  245.         WaveTableStateRec*        Scan;
  246.  
  247.         Scan = WaveTableStateFreeList;
  248.         while (Scan != NIL)
  249.             {
  250.                 if (Scan == Object)
  251.                     {
  252.                         PRERR(ForceAbort,"CheckValidWaveTableState:  state is on free list");
  253.                     }
  254.                 Scan = Scan->Next;
  255.             }
  256.     }
  257. #else
  258. #define CheckValidWaveTableState(x) ((void)0)
  259. #endif
  260.  
  261.  
  262. /* perform one envelope update cycle */
  263. void                                    UpdateWaveTableEnvelopes(WaveTableStateRec* State)
  264.     {
  265.         FastFixedType                Temp;
  266.  
  267.         CheckPtrExistence(State);
  268.         CheckValidWaveTableState(State);
  269.  
  270.         /* this is for the benefit of resampling only -- envelope generators do their */
  271.         /* own pre-origin sequencing */
  272.         if (State->PreStartCountdown > 0)
  273.             {
  274.                 State->PreStartCountdown -= 1;
  275.             }
  276.  
  277.         Temp = LFOGenUpdateCycle(State->IndexLFOGenerator,EnvelopeUpdate(
  278.             State->WaveTableIndexEnvelope));
  279.         if (Temp < 0)
  280.             {
  281.                 Temp = 0;
  282.             }
  283.         else if (Temp > Int2FastFixed(State->NumberOfTables - 1))
  284.             {
  285.                 Temp = Int2FastFixed(State->NumberOfTables - 1);
  286.             }
  287.         State->WaveTableIndex = Temp;
  288.  
  289.         Temp = LFOGenUpdateCycle(State->LoudnessLFOGenerator,EnvelopeUpdate(
  290.             State->WaveTableLoudnessEnvelope));
  291.         /* fast fixed has a very narrow range, so overflow can't be permitted: */
  292.         /* 15x15->30 bits, with 2 extra bits; we use one for sign and the other */
  293.         /* to permit the representation of 1 and -1. */
  294.         if (State->Template.StereoPlayback == eSampleMono)
  295.             {
  296.                 if (Temp < - Int2FastFixed(1))
  297.                     {
  298.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  299.                             - FastFixed2Float(Temp));
  300.                         Temp = - Int2FastFixed(1);
  301.                     }
  302.                 else if (Temp > Int2FastFixed(1))
  303.                     {
  304.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  305.                             FastFixed2Float(Temp));
  306.                         Temp = Int2FastFixed(1);
  307.                     }
  308.                 State->OverallLoudness = Temp;
  309.             }
  310.          else
  311.             {
  312.                 FastFixedType                LeftVolumeScaling;
  313.                 FastFixedType                RightVolumeScaling;
  314.                 FastFixedType                MaxVolScaling;
  315.                 FastFixedType                MaxTemp;
  316.  
  317.                 LeftVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
  318.                     Int2FastFixed(1) - State->Panning);
  319.                 RightVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
  320.                     Int2FastFixed(1) + State->Panning);
  321.  
  322.                 if (((LeftVolumeScaling >= 0) ? LeftVolumeScaling : (- LeftVolumeScaling))
  323.                     > ((RightVolumeScaling >= 0) ? RightVolumeScaling : (- RightVolumeScaling)))
  324.                     {
  325.                         MaxVolScaling = ((LeftVolumeScaling >= 0)
  326.                             ? LeftVolumeScaling : (- LeftVolumeScaling));
  327.                     }
  328.                  else
  329.                     {
  330.                         MaxVolScaling = ((RightVolumeScaling >= 0)
  331.                             ? RightVolumeScaling : (- RightVolumeScaling));
  332.                     }
  333.                 MaxTemp = Double2FastFixed((float)1 / FastFixed2Float(MaxVolScaling));
  334.                 if (Temp < - MaxTemp)
  335.                     {
  336.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  337.                             - FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
  338.                         Temp = - MaxTemp;
  339.                     }
  340.                 else if (Temp > MaxTemp)
  341.                     {
  342.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  343.                             FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
  344.                         Temp = MaxTemp;
  345.                     }
  346.  
  347.                 State->LeftLoudness = FastFixedTimesFastFixedToFastFixed(
  348.                     LeftVolumeScaling,Temp);
  349.                 State->RightLoudness = FastFixedTimesFastFixedToFastFixed(
  350.                     RightVolumeScaling,Temp);
  351.             }
  352.     }
  353.  
  354.  
  355. /* dispose of the wave table state record */
  356. void                                    DisposeWaveTableState(WaveTableStateRec* State)
  357.     {
  358.         CheckPtrExistence(State);
  359.         CheckValidWaveTableState(State);
  360.  
  361.         DisposeEnvelopeStateRecord(State->WaveTableIndexEnvelope);
  362.         DisposeLFOGenerator(State->IndexLFOGenerator);
  363.         DisposeEnvelopeStateRecord(State->WaveTableLoudnessEnvelope);
  364.         DisposeLFOGenerator(State->LoudnessLFOGenerator);
  365.  
  366.         State->Next = WaveTableStateFreeList;
  367.         WaveTableStateFreeList = State;
  368.     }
  369.  
  370.  
  371. /* dispose of the wave table information template */
  372. void                                    DisposeWaveTableTemplate(WaveTableTemplateRec* Template)
  373.     {
  374.         CheckPtrExistence(Template);
  375.         CheckValidWaveTableTemplate(Template);
  376.  
  377.         DisposeMultisample(Template->WaveTableSourceSelector);
  378.  
  379.         Template->Next = WaveTableTemplateFreeList;
  380.         WaveTableTemplateFreeList = Template;
  381.     }
  382.  
  383.  
  384. /* create a new wave table template */
  385. WaveTableTemplateRec*    NewWaveTableTemplate(struct OscillatorRec* Oscillator,
  386.                                                 float EnvelopeTicksPerSecond, long SamplingRate,
  387.                                                 MyBoolean Stereo, MyBoolean TimeInterp, MyBoolean WaveInterp,
  388.                                                 ErrorDaemonRec* ErrorDaemon)
  389.     {
  390.         WaveTableTemplateRec*    Template;
  391.  
  392.         CheckPtrExistence(ErrorDaemon);
  393.         CheckPtrExistence(Oscillator);
  394.         ERROR(OscillatorGetWhatKindItIs(Oscillator) != eOscillatorWaveTable,PRERR(ForceAbort,
  395.             "NewWaveTableTemplate:  oscillator is not a wave table"));
  396.  
  397.         if (WaveTableTemplateFreeList != NIL)
  398.             {
  399.                 Template = WaveTableTemplateFreeList;
  400.                 WaveTableTemplateFreeList = WaveTableTemplateFreeList->Next;
  401.             }
  402.          else
  403.             {
  404.                 Template = (WaveTableTemplateRec*)AllocPtrCanFail(sizeof(WaveTableTemplateRec),
  405.                     "WaveTableTemplateRec");
  406.                 if (Template == NIL)
  407.                     {
  408.                         return NIL;
  409.                     }
  410.             }
  411.         EXECUTE(Template->Next = (WaveTableTemplateRec*)0x81818181;)
  412.  
  413.         Template->WaveTableSourceSelector = NewMultisampleWaveTable(
  414.             OscillatorGetSampleIntervalList(Oscillator));
  415.         if (Template->WaveTableSourceSelector == NIL)
  416.             {
  417.              FailurePoint1:
  418.                 Template->Next = WaveTableTemplateFreeList;
  419.                 WaveTableTemplateFreeList = Template;
  420.                 return NIL;
  421.             }
  422.  
  423.         Template->FinalOutputSamplingRate = SamplingRate;
  424.         Template->EnvelopeTicksPerSecond = EnvelopeTicksPerSecond;
  425.         Template->OverallOscillatorLoudness = OscillatorGetOutputLoudness(Oscillator);
  426.  
  427.         /* it might be better to handle divisor and multiplier separately -- we would */
  428.         /* want to do that if we were trying to guarantee that all harmonic */
  429.         /* oscillators ran in lock-step */
  430.         Template->FrequencyMultiplier = OscillatorGetFrequencyMultiplier(Oscillator)
  431.             / OscillatorGetFrequencyDivisor(Oscillator);
  432.  
  433.         Template->StereoBias = OscillatorGetStereoBias(Oscillator);
  434.         Template->TimeDisplacement = OscillatorGetTimeDisplacement(Oscillator);
  435.  
  436.         if (Stereo)
  437.             {
  438.                 Template->StereoPlayback = eSampleStereo;
  439.             }
  440.          else
  441.             {
  442.                 Template->StereoPlayback = eSampleMono;
  443.             }
  444.         Template->InterpolateThroughTime = TimeInterp;
  445.         Template->InterpolateAcrossWaves = WaveInterp;
  446.         Template->IncludeInFinalOutput = IncludeOscillatorInFinalOutput(Oscillator);
  447.  
  448.         /* these are just references */
  449.         Template->LoudnessEnvelopeTemplate = OscillatorGetLoudnessEnvelope(Oscillator);
  450.         Template->LoudnessLFOTemplate = OscillatorGetLoudnessLFOList(Oscillator);
  451.         Template->IndexEnvelopeTemplate = OscillatorGetExcitationEnvelope(Oscillator);
  452.         Template->IndexLFOTemplate = OscillatorGetExcitationLFOList(Oscillator);
  453.  
  454.         /* another reference */
  455.         Template->ErrorDaemon = ErrorDaemon;
  456.  
  457.         return Template;
  458.     }
  459.  
  460.  
  461. /* create a new wave table state object. */
  462. WaveTableStateRec*        NewWaveTableState(WaveTableTemplateRec* Template,
  463.                                                 float FreqForMultisampling, float Accent1, float Accent2,
  464.                                                 float Accent3, float Accent4, float Loudness, float HurryUp,
  465.                                                 long* PreOriginTimeOut, float StereoPosition,
  466.                                                 float InitialFrequency, float LoudnessLFOAmplitudeScaling,
  467.                                                 float LoudnessLFOFrequencyScaling, MyBoolean DoingModulation)
  468.     {
  469.         WaveTableStateRec*    State;
  470.         long                                MaxPreOrigin;
  471.         long                                OnePreOrigin;
  472.  
  473.         CheckPtrExistence(Template);
  474.         CheckValidWaveTableTemplate(Template);
  475.  
  476.         if (WaveTableStateFreeList != NIL)
  477.             {
  478.                 State = WaveTableStateFreeList;
  479.                 WaveTableStateFreeList = WaveTableStateFreeList->Next;
  480.             }
  481.          else
  482.             {
  483.                 State = (WaveTableStateRec*)AllocPtrCanFail(sizeof(WaveTableStateRec),
  484.                     "WaveTableStateRec");
  485.                 if (State == NIL)
  486.                     {
  487.                      FailurePoint1:
  488.                         return NIL;
  489.                     }
  490.             }
  491.         EXECUTE(State->Next = (WaveTableStateRec*)0x81818181;)
  492.  
  493.         State->Template = *Template;
  494.  
  495.         MaxPreOrigin = 0;
  496.  
  497.         Double2LongLong(0,State->WaveTableSamplePosition);
  498.         /* State->WaveTableSamplePositionDifferential specified in separate call */
  499.  
  500.         State->NoteLoudnessScaling = Loudness * Template->OverallOscillatorLoudness;
  501.  
  502.         State->DoingModulation = DoingModulation;
  503.  
  504.         State->WaveTableWasDefined = GetMultisampleReferenceWaveTable(
  505.             Template->WaveTableSourceSelector,FreqForMultisampling,&(State->WaveTableMatrix),
  506.             &(State->FramesPerTable),&(State->NumberOfTables),&(State->TableNumBits));
  507.  
  508.         /* Template->IncludeInFinalOutput: */
  509.         /*   the routine pointer is not used for modulation */
  510.         /* State->WaveTableWasDefined: */
  511.         /*   if there is no wave table defined for the current pitch, then we don't */
  512.         /*   bother generating any data */
  513.         /* State->FramesPerTable > 0: */
  514.         /*   if the wave table is empty, then we don't do any work (and we must not, */
  515.         /*   since array accesses would cause a crash) */
  516.         if (Template->IncludeInFinalOutput && State->WaveTableWasDefined
  517.             && (State->FramesPerTable > 0))
  518.             {
  519.                 if (Template->StereoPlayback == eSampleStereo)
  520.                     {
  521.                         if (State->TableNumBits == eSample16bit)
  522.                             {
  523.                                 if (Template->InterpolateAcrossWaves)
  524.                                     {
  525.                                         State->WaveTableGenSamples = &Wave_Stereo_16BitIn_YesTime_YesWave;
  526.                                     }
  527.                                 else if (Template->InterpolateThroughTime)
  528.                                     {
  529.                                         State->WaveTableGenSamples = &Wave_Stereo_16BitIn_YesTime_NoWave;
  530.                                     }
  531.                                 else
  532.                                     {
  533.                                         State->WaveTableGenSamples = &Wave_Stereo_16BitIn_NoTime_NoWave;
  534.                                     }
  535.                             }
  536.                          else
  537.                             {
  538.                                 if (Template->InterpolateAcrossWaves)
  539.                                     {
  540.                                         State->WaveTableGenSamples = &Wave_Stereo_8BitIn_YesTime_YesWave;
  541.                                     }
  542.                                 else if (Template->InterpolateThroughTime)
  543.                                     {
  544.                                         State->WaveTableGenSamples = &Wave_Stereo_8BitIn_YesTime_NoWave;
  545.                                     }
  546.                                 else
  547.                                     {
  548.                                         State->WaveTableGenSamples = &Wave_Stereo_8BitIn_NoTime_NoWave;
  549.                                     }
  550.                             }
  551.                     }
  552.                  else
  553.                     {
  554.                         if (State->TableNumBits == eSample16bit)
  555.                             {
  556.                                 if (Template->InterpolateAcrossWaves)
  557.                                     {
  558.                                         State->WaveTableGenSamples = &Wave_Mono_16BitIn_YesTime_YesWave;
  559.                                     }
  560.                                 else if (Template->InterpolateThroughTime)
  561.                                     {
  562.                                         State->WaveTableGenSamples = &Wave_Mono_16BitIn_YesTime_NoWave;
  563.                                     }
  564.                                 else
  565.                                     {
  566.                                         State->WaveTableGenSamples = &Wave_Mono_16BitIn_NoTime_NoWave;
  567.                                     }
  568.                             }
  569.                          else
  570.                             {
  571.                                 if (Template->InterpolateAcrossWaves)
  572.                                     {
  573.                                         State->WaveTableGenSamples = &Wave_Mono_8BitIn_YesTime_YesWave;
  574.                                     }
  575.                                 else if (Template->InterpolateThroughTime)
  576.                                     {
  577.                                         State->WaveTableGenSamples = &Wave_Mono_8BitIn_YesTime_NoWave;
  578.                                     }
  579.                                 else
  580.                                     {
  581.                                         State->WaveTableGenSamples = &Wave_Mono_8BitIn_NoTime_NoWave;
  582.                                     }
  583.                             }
  584.                     }
  585.             }
  586.          else
  587.             {
  588.                 State->WaveTableGenSamples = &Wave_NoOutput;
  589.             }
  590.  
  591.         State->PreStartCountdown = Template->TimeDisplacement
  592.             * Template->EnvelopeTicksPerSecond + 0.5;
  593.         if (- State->PreStartCountdown > MaxPreOrigin)
  594.             {
  595.                 MaxPreOrigin = - State->PreStartCountdown;
  596.             }
  597.  
  598.         /* State->WaveTableIndex determined by envelope update */
  599.         State->WaveTableIndexEnvelope = NewEnvelopeStateRecord(
  600.             Template->IndexEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,InitialFrequency,
  601.             State->NumberOfTables - 1,HurryUp,Template->EnvelopeTicksPerSecond,&OnePreOrigin);
  602.         if (State->WaveTableIndexEnvelope == NIL)
  603.             {
  604.              FailurePoint2:
  605.                 State->Next = WaveTableStateFreeList;
  606.                 WaveTableStateFreeList = State;
  607.                 goto FailurePoint1;
  608.             }
  609.         if (OnePreOrigin > MaxPreOrigin)
  610.             {
  611.                 MaxPreOrigin = OnePreOrigin;
  612.             }
  613.         State->IndexLFOGenerator = NewLFOGenerator(Template->IndexLFOTemplate,
  614.             &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
  615.             Template->EnvelopeTicksPerSecond,State->NumberOfTables - 1,
  616.             1/* no per-note adjustable frequency control for index modulation */,
  617.             eLFOArithDefault,1,FreqForMultisampling);
  618.         if (State->IndexLFOGenerator == NIL)
  619.             {
  620.              FailurePoint3:
  621.                 DisposeEnvelopeStateRecord(State->WaveTableIndexEnvelope);
  622.                 goto FailurePoint2;
  623.             }
  624.         if (OnePreOrigin > MaxPreOrigin)
  625.             {
  626.                 MaxPreOrigin = OnePreOrigin;
  627.             }
  628.  
  629.         /* State->OverallLoudness, State->LeftLoudness, State->RightLoudness */
  630.         /* are determined by the envelope update */
  631.         StereoPosition += Template->StereoBias;
  632.         if (StereoPosition < -1)
  633.             {
  634.                 StereoPosition = -1;
  635.             }
  636.         else if (StereoPosition > 1)
  637.             {
  638.                 StereoPosition = 1;
  639.             }
  640.         State->Panning = Double2FastFixed(StereoPosition);
  641.         State->WaveTableLoudnessEnvelope = NewEnvelopeStateRecord(
  642.             Template->LoudnessEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,
  643.             InitialFrequency,DoingModulation ? 1 : State->NoteLoudnessScaling,HurryUp,
  644.             Template->EnvelopeTicksPerSecond,&OnePreOrigin);
  645.         if (State->WaveTableLoudnessEnvelope == NIL)
  646.             {
  647.              FailurePoint4:
  648.                 DisposeLFOGenerator(State->IndexLFOGenerator);
  649.                 goto FailurePoint3;
  650.             }
  651.         if (OnePreOrigin > MaxPreOrigin)
  652.             {
  653.                 MaxPreOrigin = OnePreOrigin;
  654.             }
  655.         State->LoudnessLFOGenerator = NewLFOGenerator(Template->LoudnessLFOTemplate,
  656.             &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
  657.             Template->EnvelopeTicksPerSecond,LoudnessLFOAmplitudeScaling,
  658.             LoudnessLFOFrequencyScaling,eLFOArithDefault,
  659.             DoingModulation ? 1 : State->NoteLoudnessScaling,FreqForMultisampling);
  660.         if (State->LoudnessLFOGenerator == NIL)
  661.             {
  662.              FailurePoint5:
  663.                 DisposeEnvelopeStateRecord(State->WaveTableLoudnessEnvelope);
  664.                 goto FailurePoint4;
  665.             }
  666.         if (OnePreOrigin > MaxPreOrigin)
  667.             {
  668.                 MaxPreOrigin = OnePreOrigin;
  669.             }
  670.  
  671.         *PreOriginTimeOut = MaxPreOrigin;
  672.         return State;
  673.     }
  674.  
  675.  
  676. /* fix up pre-origin time for the wave table state object */
  677. void                                    FixUpWaveTableStatePreOrigin(WaveTableStateRec* State,
  678.                                                 long ActualPreOrigin)
  679.     {
  680.         CheckPtrExistence(State);
  681.         CheckValidWaveTableState(State);
  682.  
  683.         EnvelopeStateFixUpInitialDelay(State->WaveTableIndexEnvelope,ActualPreOrigin);
  684.         EnvelopeStateFixUpInitialDelay(State->WaveTableLoudnessEnvelope,ActualPreOrigin);
  685.         LFOGeneratorFixEnvelopeOrigins(State->IndexLFOGenerator,ActualPreOrigin);
  686.         LFOGeneratorFixEnvelopeOrigins(State->LoudnessLFOGenerator,ActualPreOrigin);
  687.  
  688.         State->PreStartCountdown += ActualPreOrigin;
  689.     }
  690.  
  691.  
  692. /* set a new frequency for a wave table state object.  used for portamento */
  693. /* and modulation of frequency (vibrato) */
  694. void                                    WaveTableStateNewFrequency(WaveTableStateRec* State,
  695.                                                 float NewFrequencyHertz)
  696.     {
  697.         CheckPtrExistence(State);
  698.         CheckValidWaveTableState(State);
  699.  
  700.         Double2LongLong((NewFrequencyHertz * State->Template.FrequencyMultiplier)
  701.             / State->Template.FinalOutputSamplingRate * State->FramesPerTable,
  702.             State->WaveTableSamplePositionDifferential);
  703.     }
  704.  
  705.  
  706. /* send a key-up signal to one of the oscillators */
  707. void                                    WaveTableKeyUpSustain1(WaveTableStateRec* State)
  708.     {
  709.         CheckPtrExistence(State);
  710.         CheckValidWaveTableState(State);
  711.         LFOGeneratorKeyUpSustain1(State->IndexLFOGenerator);
  712.         LFOGeneratorKeyUpSustain1(State->LoudnessLFOGenerator);
  713.         EnvelopeKeyUpSustain1(State->WaveTableIndexEnvelope);
  714.         EnvelopeKeyUpSustain1(State->WaveTableLoudnessEnvelope);
  715.     }
  716.  
  717.  
  718. /* send a key-up signal to one of the oscillators */
  719. void                                    WaveTableKeyUpSustain2(WaveTableStateRec* State)
  720.     {
  721.         CheckPtrExistence(State);
  722.         CheckValidWaveTableState(State);
  723.         LFOGeneratorKeyUpSustain2(State->IndexLFOGenerator);
  724.         LFOGeneratorKeyUpSustain2(State->LoudnessLFOGenerator);
  725.         EnvelopeKeyUpSustain2(State->WaveTableIndexEnvelope);
  726.         EnvelopeKeyUpSustain2(State->WaveTableLoudnessEnvelope);
  727.     }
  728.  
  729.  
  730. /* send a key-up signal to one of the oscillators */
  731. void                                    WaveTableKeyUpSustain3(WaveTableStateRec* State)
  732.     {
  733.         CheckPtrExistence(State);
  734.         CheckValidWaveTableState(State);
  735.         LFOGeneratorKeyUpSustain3(State->IndexLFOGenerator);
  736.         LFOGeneratorKeyUpSustain3(State->LoudnessLFOGenerator);
  737.         EnvelopeKeyUpSustain3(State->WaveTableIndexEnvelope);
  738.         EnvelopeKeyUpSustain3(State->WaveTableLoudnessEnvelope);
  739.     }
  740.  
  741.  
  742. /* restart a wave table oscillator.  this is used for tie continuations */
  743. void                                    RestartWaveTableState(WaveTableStateRec* State,
  744.                                                 float NewFreqMultisampling, float NewAccent1, float NewAccent2,
  745.                                                 float NewAccent3, float NewAccent4, float NewLoudness,
  746.                                                 float NewHurryUp, MyBoolean RetriggerEnvelopes,
  747.                                                 float NewStereoPosition, float NewInitialFrequency,
  748.                                                 float NewLoudnessLFOAmplitudeScaling,
  749.                                                 float NewLoudnessLFOFrequencyScaling)
  750.     {
  751.         CheckPtrExistence(State);
  752.         CheckValidWaveTableState(State);
  753.  
  754.         NewStereoPosition += State->Template.StereoBias;
  755.         if (NewStereoPosition < -1)
  756.             {
  757.                 NewStereoPosition = -1;
  758.             }
  759.         else if (NewStereoPosition > 1)
  760.             {
  761.                 NewStereoPosition = 1;
  762.             }
  763.         State->Panning = Double2FastFixed(NewStereoPosition);
  764.  
  765.         State->NoteLoudnessScaling = NewLoudness * State->Template.OverallOscillatorLoudness;
  766.  
  767.         EnvelopeRetriggerFromOrigin(State->WaveTableIndexEnvelope,NewAccent1,NewAccent2,
  768.             NewAccent3,NewAccent4,NewInitialFrequency,State->DoingModulation ? 1
  769.             : State->NoteLoudnessScaling,NewHurryUp,
  770.             State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
  771.         EnvelopeRetriggerFromOrigin(State->WaveTableLoudnessEnvelope,NewAccent1,
  772.             NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,State->DoingModulation ? 1
  773.             : State->NoteLoudnessScaling,NewHurryUp,
  774.             State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
  775.         LFOGeneratorRetriggerFromOrigin(State->IndexLFOGenerator,NewAccent1,NewAccent2,
  776.             NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,
  777.             State->Template.EnvelopeTicksPerSecond,1,1,RetriggerEnvelopes);
  778.         LFOGeneratorRetriggerFromOrigin(State->LoudnessLFOGenerator,NewAccent1,
  779.             NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,
  780.             State->Template.EnvelopeTicksPerSecond,NewLoudnessLFOAmplitudeScaling,
  781.             NewLoudnessLFOFrequencyScaling,RetriggerEnvelopes);
  782.     }
  783.  
  784.  
  785. /* generate one sequence of samples */
  786. void                                    WaveTableGenSamples(WaveTableStateRec* State,
  787.                                                 long SampleCount, largefixedsigned* RawBuffer)
  788.     {
  789.         CheckPtrExistence(State);
  790.         CheckValidWaveTableState(State);
  791.  
  792.         if (State->PreStartCountdown <= 0)
  793.             {
  794.                 (*State->WaveTableGenSamples)(State,SampleCount,RawBuffer);
  795.             }
  796.     }
  797.  
  798.  
  799. /* find out if the wave table oscillator has finished */
  800. MyBoolean                            WaveTableIsItFinished(WaveTableStateRec* State)
  801.     {
  802.         CheckPtrExistence(State);
  803.         CheckValidWaveTableState(State);
  804.  
  805.         /* we are finished when one of the following conditions is met: */
  806.         /*  - output volume is zero AND loudness envelope is finished */
  807.         /*  - we are not generating any signal */
  808.         if (!State->WaveTableWasDefined)
  809.             {
  810.                 return True;
  811.             }
  812.         if (IsEnvelopeAtEnd(State->WaveTableLoudnessEnvelope))
  813.             {
  814.                 if (State->Template.StereoPlayback == eSampleStereo)
  815.                     {
  816.                         if ((State->LeftLoudness == 0) && (State->RightLoudness == 0))
  817.                             {
  818.                                 return True;
  819.                             }
  820.                     }
  821.                  else
  822.                     {
  823.                         if (State->OverallLoudness == 0)
  824.                             {
  825.                                 return True;
  826.                             }
  827.                     }
  828.             }
  829.         return IsEnvelopeAtEnd(State->WaveTableLoudnessEnvelope);
  830.     }
  831.  
  832.  
  833. /* generate a single sample (called for modulation chains) */
  834. /* OutputPlace should have 1 entry for mono output or 2 entries for stereo output */
  835. float                                    WaveTableGenOneSample(WaveTableStateRec* State,
  836.                                                 ModulationTypes* PhaseGenModulateHow,
  837.                                                 float* PhaseGenModulationScaling,
  838.                                                 float* PhaseGenModulationOrigin,
  839.                                                 float* PhaseGenOldValues,
  840.                                                 long* PhaseGenIndirectionTable,
  841.                                                 long NumberOfPhaseGenModulators,
  842.                                                 ModulationTypes* OutputModulateHow,
  843.                                                 float* OutputModulationScaling,
  844.                                                 float* OutputModulationOrigin,
  845.                                                 float* OutputOldValues,
  846.                                                 long* OutputIndirectionTable,
  847.                                                 long NumberOfOutputModulators,
  848.                                                 largefixedsigned* OutputPlace)
  849.     {
  850.         float                                ReturnValue;
  851.         LongLongRec                    FrameIndex;
  852.         signed long                    Final; /* both 16-bit int & largefixedsigned */
  853.  
  854.         CheckPtrExistence(State);
  855.         CheckValidWaveTableState(State);
  856.  
  857.         /* should we bother doing any work? */
  858.         if (!State->WaveTableWasDefined || (State->FramesPerTable == 0)
  859.             || (State->PreStartCountdown > 0))
  860.             {
  861.                 /* modulate against zero */
  862.                 if (State->Template.StereoPlayback == eSampleStereo)
  863.                     {
  864.                         OutputPlace[0] += double2largefixed(ApplyModulation(0,OutputModulateHow,
  865.                             OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
  866.                             OutputIndirectionTable,NumberOfOutputModulators));
  867.                         OutputPlace[1] += double2largefixed(ApplyModulation(0,OutputModulateHow,
  868.                             OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
  869.                             OutputIndirectionTable,NumberOfOutputModulators));
  870.                     }
  871.                  else
  872.                     {
  873.                         OutputPlace[0] += double2largefixed(ApplyModulation(0,OutputModulateHow,
  874.                             OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
  875.                             OutputIndirectionTable,NumberOfOutputModulators));
  876.                     }
  877.                 return 0;
  878.             }
  879.  
  880.         /* generate the sample position */
  881.         /* we want the modulation to be the same no matter how large the wavetable */
  882.         /* is, so we need to normalize the wave table index. */
  883.         Double2LongLong(ApplyModulation(LongLong2Double(State->WaveTableSamplePosition)
  884.             / State->FramesPerTable,PhaseGenModulateHow,PhaseGenModulationScaling,
  885.             PhaseGenModulationOrigin,PhaseGenOldValues,PhaseGenIndirectionTable,
  886.             NumberOfPhaseGenModulators) * State->FramesPerTable,FrameIndex);
  887.  
  888.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  889.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  890.             "WaveTableGenOneSample:  wave index out of range"));
  891.  
  892.         /* big selector of the thing to do */
  893.         if (State->Template.InterpolateAcrossWaves)
  894.             {
  895.                 /* wave & time interp */
  896.                 /* do the stuff for one wave table */
  897.                 if (State->TableNumBits == eSample16bit)
  898.                     {
  899.                         /* 16-bit sampling, wave interp, time interp */
  900.  
  901.                         signed short*                WaveData0;
  902.                         signed short*                WaveData1;
  903.                         FastFixedType                Wave0Weight;
  904.  
  905.                         FastFixedType                LeftWeight;
  906.                         long                                ArraySubscript;
  907.                         signed long                    Left0Value;
  908.                         signed long                    Right0Value;
  909.                         signed long                    Left1Value;
  910.                         signed long                    Right1Value;
  911.                         FastFixedType                Wave0Temp;
  912.  
  913.                         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  914.                             {
  915.                                 /* this is done in case the wave table index is at the maximum, */
  916.                                 /* in which case there is no table+1 to interpolate with. */
  917.                                 goto W16BitTimeNoWave;
  918.                             }
  919.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  920.                             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  921.                             State->WaveTableIndex)]));
  922.                         WaveData0 = (signed short*)(State->WaveTableMatrix[
  923.                             FastFixed2Int(State->WaveTableIndex)]);
  924.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  925.                             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  926.                             State->WaveTableIndex) + 1]));
  927.                         WaveData1 = (signed short*)(State->WaveTableMatrix[
  928.                             FastFixed2Int(State->WaveTableIndex) + 1]);
  929.                         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  930.  
  931.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  932.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  933.                         /* L+F(R-L) -- applied twice */
  934.                         Left0Value = WaveData0[ArraySubscript];
  935.                         Right0Value = WaveData0[ArraySubscript + 1];
  936.                         Left1Value = WaveData1[ArraySubscript];
  937.                         Right1Value = WaveData1[ArraySubscript + 1];
  938.                         Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  939.                         Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  940.                             * (Right1Value - Left1Value)) >> 15)) - Wave0Temp) >> 15);
  941.                     }
  942.                  else
  943.                     {
  944.                         /* 8-bit sampling, wave interp, time interp */
  945.  
  946.                         signed char*                WaveData0;
  947.                         signed char*                WaveData1;
  948.                         FastFixedType                Wave0Weight;
  949.  
  950.                         FastFixedType                LeftWeight;
  951.                         long                                ArraySubscript;
  952.                         signed long                    Left0Value;
  953.                         signed long                    Right0Value;
  954.                         signed long                    Left1Value;
  955.                         signed long                    Right1Value;
  956.                         FastFixedType                Wave0Temp;
  957.  
  958.                         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  959.                             {
  960.                                 /* this is done in case the wave table index is at the maximum, */
  961.                                 /* in which case there is no table+1 to interpolate with. */
  962.                                 goto W8BitTimeNoWave;
  963.                             }
  964.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  965.                             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  966.                             State->WaveTableIndex)]));
  967.                         WaveData0 = (signed char*)(State->WaveTableMatrix[
  968.                             FastFixed2Int(State->WaveTableIndex)]);
  969.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  970.                             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  971.                             State->WaveTableIndex) + 1]));
  972.                         WaveData1 = (signed char*)(State->WaveTableMatrix[
  973.                             FastFixed2Int(State->WaveTableIndex) + 1]);
  974.                         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  975.  
  976.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  977.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  978.                         /* L+F(R-L) -- applied twice */
  979.                         Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
  980.                         Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
  981.                         Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
  982.                         Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
  983.                         Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  984.                         Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  985.                             * (Right1Value - Left1Value)) >> 15) - Wave0Temp)) >> 15);
  986.                     }
  987.             }
  988.         else if (State->Template.InterpolateThroughTime)
  989.             {
  990.                 /* time interp */
  991.                 /* do the stuff for one wave table */
  992.                 if (State->TableNumBits == eSample16bit)
  993.                     {
  994.                         /* 16-bit sampling, time interp */
  995.  
  996.                         signed short*                WaveData;
  997.  
  998.                         FastFixedType                LeftWeight;
  999.                         long                                ArraySubscript;
  1000.                         signed long                    LeftValue;
  1001.                         signed long                    RightValue;
  1002.  
  1003.                      W16BitTimeNoWave:
  1004.  
  1005.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1006.                             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1007.                             State->WaveTableIndex)]));
  1008.                         WaveData = (signed short*)(State->WaveTableMatrix[
  1009.                             FastFixed2Int(State->WaveTableIndex)]);
  1010.  
  1011.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1012.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1013.                         /* L+F(R-L) */
  1014.                         LeftValue = WaveData[ArraySubscript];
  1015.                         RightValue = WaveData[ArraySubscript + 1];
  1016.                         Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1017.                     }
  1018.                  else
  1019.                     {
  1020.                         /* 8-bit sampling, time interp */
  1021.  
  1022.                         signed char*                WaveData;
  1023.  
  1024.                         FastFixedType                LeftWeight;
  1025.                         long                                ArraySubscript;
  1026.                         signed long                    LeftValue;
  1027.                         signed long                    RightValue;
  1028.  
  1029.                      W8BitTimeNoWave:
  1030.  
  1031.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1032.                             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1033.                             State->WaveTableIndex)]));
  1034.                         WaveData = (signed char*)(State->WaveTableMatrix[
  1035.                             FastFixed2Int(State->WaveTableIndex)]);
  1036.  
  1037.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1038.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1039.                         /* L+F(R-L) */
  1040.                         LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
  1041.                         RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1042.                         Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1043.                     }
  1044.             }
  1045.         else
  1046.             {
  1047.                 /* no interp */
  1048.                 /* do the stuff for one wave table */
  1049.                 if (State->TableNumBits == eSample16bit)
  1050.                     {
  1051.                         /* 16-bit sampling */
  1052.  
  1053.                         signed short*                WaveData;
  1054.  
  1055.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1056.                             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1057.                             State->WaveTableIndex)]));
  1058.                         WaveData = (signed short*)(State->WaveTableMatrix[
  1059.                             FastFixed2Int(State->WaveTableIndex)]);
  1060.  
  1061.                         Final = WaveData[LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1)];
  1062.                     }
  1063.                  else
  1064.                     {
  1065.                         /* 8-bit sampling */
  1066.  
  1067.                         signed char*                WaveData;
  1068.  
  1069.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1070.                             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1071.                             State->WaveTableIndex)]));
  1072.                         WaveData = (signed char*)(State->WaveTableMatrix[
  1073.                             FastFixed2Int(State->WaveTableIndex)]);
  1074.  
  1075.                         Final = WaveData[LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1)];
  1076.                     }
  1077.             }
  1078.  
  1079.         if (State->Template.StereoPlayback == eSampleStereo)
  1080.             {
  1081.                 ReturnValue = ((float)Final / MAX16BIT) * ((FastFixed2Float(
  1082.                     State->LeftLoudness) + FastFixed2Float(State->RightLoudness)) / 2);
  1083.                 if (State->Template.IncludeInFinalOutput)
  1084.                     {
  1085.                         OutputPlace[0] += double2largefixed(ApplyModulation(largefixed2single(
  1086.                             FastFixedTimes16BitTo24Bit((signed long)(State->LeftLoudness
  1087.                             * State->NoteLoudnessScaling),Final)),OutputModulateHow,
  1088.                             OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
  1089.                             OutputIndirectionTable,NumberOfOutputModulators));;
  1090.                         OutputPlace[1] += double2largefixed(ApplyModulation(largefixed2single(
  1091.                             FastFixedTimes16BitTo24Bit((signed long)(State->RightLoudness
  1092.                             * State->NoteLoudnessScaling),Final)),OutputModulateHow,
  1093.                             OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
  1094.                             OutputIndirectionTable,NumberOfOutputModulators));
  1095.                     }
  1096.             }
  1097.          else
  1098.             {
  1099.                 ReturnValue = ((float)Final / MAX16BIT)
  1100.                     * FastFixed2Float(State->OverallLoudness);
  1101.                 if (State->Template.IncludeInFinalOutput)
  1102.                     {
  1103.                         OutputPlace[0] += double2largefixed(ApplyModulation(largefixed2single(
  1104.                             FastFixedTimes16BitTo24Bit((signed long)(State->OverallLoudness
  1105.                             * State->NoteLoudnessScaling),Final)),OutputModulateHow,
  1106.                             OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
  1107.                             OutputIndirectionTable,NumberOfOutputModulators));
  1108.                     }
  1109.             }
  1110.  
  1111.         LongLongAdd(&State->WaveTableSamplePosition,
  1112.             &(State->WaveTableSamplePositionDifferential));
  1113.         LongLongMaskHighHalf(State->WaveTableSamplePosition,State->FramesPerTable - 1);
  1114.  
  1115.         return ReturnValue;
  1116.     }
  1117.  
  1118.  
  1119. static void                        Wave_Mono_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  1120.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1121.     {
  1122.         LongLongRec                    LocalWaveTableSamplePosition;
  1123.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1124.         unsigned long                LocalSamplePositionMask;
  1125.         signed char*                WaveData;
  1126.         FastFixedType                LocalOverallLoudness;
  1127.  
  1128.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1129.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1130.             "Wave_Mono_8BitIn_NoTime_NoWave:  wave index out of range"));
  1131.         LocalOverallLoudness = State->OverallLoudness;
  1132.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1133.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1134.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1135.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1136.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1137.             State->WaveTableIndex)]));
  1138.         WaveData = (signed char*)(State->WaveTableMatrix[
  1139.             FastFixed2Int(State->WaveTableIndex)]);
  1140.  
  1141.         while (SampleCount > 0)
  1142.             {
  1143.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalOverallLoudness,
  1144.                     WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  1145.                     & LocalSamplePositionMask]);
  1146.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1147.                     &LocalWaveTableSamplePositionDifferential);
  1148.                 SampleCount -= 1;
  1149.             }
  1150.  
  1151.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1152.     }
  1153.  
  1154.  
  1155. static void                        Wave_Stereo_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
  1156.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1157.     {
  1158.         LongLongRec                    LocalWaveTableSamplePosition;
  1159.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1160.         unsigned long                LocalSamplePositionMask;
  1161.         signed char*                WaveData;
  1162.         FastFixedType                LocalLeftLoudness;
  1163.         FastFixedType                LocalRightLoudness;
  1164.  
  1165.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1166.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1167.             "Wave_Stereo_8BitIn_NoTime_NoWave:  wave index out of range"));
  1168.         LocalLeftLoudness = State->LeftLoudness;
  1169.         LocalRightLoudness = State->RightLoudness;
  1170.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1171.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1172.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1173.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1174.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1175.             State->WaveTableIndex)]));
  1176.         WaveData = (signed char*)(State->WaveTableMatrix[
  1177.             FastFixed2Int(State->WaveTableIndex)]);
  1178.  
  1179.         while (SampleCount > 0)
  1180.             {
  1181.                 signed long                    SamplePoint;
  1182.  
  1183.                 SamplePoint = WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  1184.                     & LocalSamplePositionMask];
  1185.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalLeftLoudness,SamplePoint);
  1186.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalRightLoudness,SamplePoint);
  1187.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1188.                     &LocalWaveTableSamplePositionDifferential);
  1189.                 SampleCount -= 1;
  1190.             }
  1191.  
  1192.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1193.     }
  1194.  
  1195.  
  1196. static void                        Wave_Mono_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  1197.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1198.     {
  1199.         LongLongRec                    LocalWaveTableSamplePosition;
  1200.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1201.         unsigned long                LocalSamplePositionMask;
  1202.         signed short*                WaveData;
  1203.         FastFixedType                LocalOverallLoudness;
  1204.  
  1205.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1206.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1207.             "Wave_Mono_16BitIn_NoTime_NoWave:  wave index out of range"));
  1208.         LocalOverallLoudness = State->OverallLoudness;
  1209.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1210.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1211.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1212.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1213.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1214.             State->WaveTableIndex)]));
  1215.         WaveData = (signed short*)(State->WaveTableMatrix[
  1216.             FastFixed2Int(State->WaveTableIndex)]);
  1217.  
  1218.         while (SampleCount > 0)
  1219.             {
  1220.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  1221.                     WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  1222.                     & LocalSamplePositionMask]);
  1223.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1224.                     &LocalWaveTableSamplePositionDifferential);
  1225.                 SampleCount -= 1;
  1226.             }
  1227.  
  1228.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1229.     }
  1230.  
  1231.  
  1232. static void                        Wave_Stereo_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
  1233.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1234.     {
  1235.         LongLongRec                    LocalWaveTableSamplePosition;
  1236.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1237.         unsigned long                LocalSamplePositionMask;
  1238.         signed short*                WaveData;
  1239.         FastFixedType                LocalLeftLoudness;
  1240.         FastFixedType                LocalRightLoudness;
  1241.  
  1242.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1243.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1244.             "Wave_Stereo_16BitIn_NoTime_NoWave:  wave index out of range"));
  1245.         LocalLeftLoudness = State->LeftLoudness;
  1246.         LocalRightLoudness = State->RightLoudness;
  1247.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1248.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1249.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1250.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1251.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1252.             State->WaveTableIndex)]));
  1253.         WaveData = (signed short*)(State->WaveTableMatrix[
  1254.             FastFixed2Int(State->WaveTableIndex)]);
  1255.  
  1256.         while (SampleCount > 0)
  1257.             {
  1258.                 signed long                    SamplePoint;
  1259.  
  1260.                 SamplePoint = WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
  1261.                     & LocalSamplePositionMask];
  1262.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,SamplePoint);
  1263.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,SamplePoint);
  1264.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1265.                     &LocalWaveTableSamplePositionDifferential);
  1266.                 SampleCount -= 1;
  1267.             }
  1268.  
  1269.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1270.     }
  1271.  
  1272.  
  1273. static void                        Wave_Mono_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1274.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1275.     {
  1276.         LongLongRec                    LocalWaveTableSamplePosition;
  1277.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1278.         unsigned long                LocalSamplePositionMask;
  1279.         signed char*                WaveData;
  1280.         FastFixedType                LocalOverallLoudness;
  1281.  
  1282.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1283.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1284.             "Wave_Mono_8BitIn_YesTime_NoWave:  wave index out of range"));
  1285.         LocalOverallLoudness = State->OverallLoudness;
  1286.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1287.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1288.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1289.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1290.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1291.             State->WaveTableIndex)]));
  1292.         WaveData = (signed char*)(State->WaveTableMatrix[
  1293.             FastFixed2Int(State->WaveTableIndex)]);
  1294.  
  1295.         while (SampleCount > 0)
  1296.             {
  1297.                 FastFixedType                LeftWeight;
  1298.                 long                                ArraySubscript;
  1299.                 signed long                    LeftValue;
  1300.                 signed long                    RightValue;
  1301.  
  1302.                 /* naive anti-aliasing worked as follows: */
  1303.                 /*  L = left sample, R = right sample, F = fractional portion of index */
  1304.                 /*  S = L(1-F) + RF */
  1305.                 /*  Craig Peeper suggested the following optimization: */
  1306.                 /*  L(1-F)+RF ==> L-LF+RF ==> L+RF-LF ==> L+F(R-L) */
  1307.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1308.                     >> (32 - FASTFIXEDPRECISION);
  1309.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1310.                     & LocalSamplePositionMask;
  1311.                 /* L+F(R-L) */
  1312.                 LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
  1313.                 RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1314.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1315.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1316.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1317.                     &LocalWaveTableSamplePositionDifferential);
  1318.                 SampleCount -= 1;
  1319.             }
  1320.  
  1321.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1322.     }
  1323.  
  1324.  
  1325. static void                        Wave_Stereo_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1326.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1327.     {
  1328.         LongLongRec                    LocalWaveTableSamplePosition;
  1329.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1330.         unsigned long                LocalSamplePositionMask;
  1331.         signed char*                WaveData;
  1332.         FastFixedType                LocalLeftLoudness;
  1333.         FastFixedType                LocalRightLoudness;
  1334.  
  1335.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1336.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1337.             "Wave_Stereo_8BitIn_YesTime_NoWave:  wave index out of range"));
  1338.         LocalLeftLoudness = State->LeftLoudness;
  1339.         LocalRightLoudness = State->RightLoudness;
  1340.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1341.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1342.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1343.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1344.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1345.             State->WaveTableIndex)]));
  1346.         WaveData = (signed char*)(State->WaveTableMatrix[
  1347.             FastFixed2Int(State->WaveTableIndex)]);
  1348.  
  1349.         while (SampleCount > 0)
  1350.             {
  1351.                 FastFixedType                LeftWeight;
  1352.                 long                                ArraySubscript;
  1353.                 signed long                    LeftValue;
  1354.                 signed long                    RightValue;
  1355.                 signed long                    CombinedValue;
  1356.  
  1357.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1358.                     >> (32 - FASTFIXEDPRECISION);
  1359.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1360.                     & LocalSamplePositionMask;
  1361.                 /* L+F(R-L) */
  1362.                 LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
  1363.                 RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1364.                 CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1365.                 /* Oh, Please Mr. Compiler, LeftValue and RightValue are dead now!!! */
  1366.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
  1367.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
  1368.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1369.                     &LocalWaveTableSamplePositionDifferential);
  1370.                 SampleCount -= 1;
  1371.             }
  1372.  
  1373.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1374.     }
  1375.  
  1376.  
  1377. static void                        Wave_Mono_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1378.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1379.     {
  1380.         LongLongRec                    LocalWaveTableSamplePosition;
  1381.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1382.         unsigned long                LocalSamplePositionMask;
  1383.         signed short*                WaveData;
  1384.         FastFixedType                LocalOverallLoudness;
  1385.  
  1386.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1387.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1388.             "Wave_Mono_16BitIn_YesTime_NoWave:  wave index out of range"));
  1389.         LocalOverallLoudness = State->OverallLoudness;
  1390.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1391.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1392.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1393.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1394.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1395.             State->WaveTableIndex)]));
  1396.         WaveData = (signed short*)(State->WaveTableMatrix[
  1397.             FastFixed2Int(State->WaveTableIndex)]);
  1398.  
  1399.         while (SampleCount > 0)
  1400.             {
  1401.                 FastFixedType                LeftWeight;
  1402.                 long                                ArraySubscript;
  1403.                 signed long                    LeftValue;
  1404.                 signed long                    RightValue;
  1405.  
  1406.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1407.                     >> (32 - FASTFIXEDPRECISION);
  1408.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1409.                     & LocalSamplePositionMask;
  1410.                 /* L+F(R-L) */
  1411.                 LeftValue = WaveData[ArraySubscript];
  1412.                 RightValue = WaveData[ArraySubscript + 1];
  1413.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1414.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1415.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1416.                     &LocalWaveTableSamplePositionDifferential);
  1417.                 SampleCount -= 1;
  1418.             }
  1419.  
  1420.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1421.     }
  1422.  
  1423.  
  1424. static void                        Wave_Stereo_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
  1425.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1426.     {
  1427.         LongLongRec                    LocalWaveTableSamplePosition;
  1428.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1429.         unsigned long                LocalSamplePositionMask;
  1430.         signed short*                WaveData;
  1431.         FastFixedType                LocalLeftLoudness;
  1432.         FastFixedType                LocalRightLoudness;
  1433.  
  1434.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1435.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1436.             "Wave_Stereo_16BitIn_YesTime_NoWave:  wave index out of range"));
  1437.         LocalLeftLoudness = State->LeftLoudness;
  1438.         LocalRightLoudness = State->RightLoudness;
  1439.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1440.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1441.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1442.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1443.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1444.             State->WaveTableIndex)]));
  1445.         WaveData = (signed short*)(State->WaveTableMatrix[
  1446.             FastFixed2Int(State->WaveTableIndex)]);
  1447.  
  1448.         while (SampleCount > 0)
  1449.             {
  1450.                 FastFixedType                LeftWeight;
  1451.                 long                                ArraySubscript;
  1452.                 signed long                    LeftValue;
  1453.                 signed long                    RightValue;
  1454.                 signed long                    CombinedValue;
  1455.  
  1456.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1457.                     >> (32 - FASTFIXEDPRECISION);
  1458.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1459.                     & LocalSamplePositionMask;
  1460.                 /* L+F(R-L) */
  1461.                 LeftValue = WaveData[ArraySubscript];
  1462.                 RightValue = WaveData[ArraySubscript + 1];
  1463.                 CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1464.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
  1465.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
  1466.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1467.                     &LocalWaveTableSamplePositionDifferential);
  1468.                 SampleCount -= 1;
  1469.             }
  1470.  
  1471.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1472.     }
  1473.  
  1474.  
  1475. static void                        Wave_Mono_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1476.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1477.     {
  1478.         LongLongRec                    LocalWaveTableSamplePosition;
  1479.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1480.         unsigned long                LocalSamplePositionMask;
  1481.         signed char*                WaveData0;
  1482.         signed char*                WaveData1;
  1483.         FastFixedType                Wave0Weight;
  1484.         FastFixedType                LocalOverallLoudness;
  1485.  
  1486.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1487.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1488.             "Wave_Mono_8BitIn_YesTime_YesWave:  wave index out of range"));
  1489.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1490.             {
  1491.                 /* this is done in case the wave table index is at the maximum, in which */
  1492.                 /* case there is no table+1 to interpolate with. */
  1493.                 Wave_Mono_8BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1494.                 return;
  1495.             }
  1496.         LocalOverallLoudness = State->OverallLoudness;
  1497.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1498.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1499.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1500.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1501.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1502.             State->WaveTableIndex)]));
  1503.         WaveData0 = (signed char*)(State->WaveTableMatrix[
  1504.             FastFixed2Int(State->WaveTableIndex)]);
  1505.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1506.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1507.             State->WaveTableIndex) + 1]));
  1508.         WaveData1 = (signed char*)(State->WaveTableMatrix[
  1509.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1510.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1511.  
  1512.         while (SampleCount > 0)
  1513.             {
  1514.                 FastFixedType                LeftWeight;
  1515.                 long                                ArraySubscript;
  1516.                 signed long                    Left0Value;
  1517.                 signed long                    Right0Value;
  1518.                 signed long                    Left1Value;
  1519.                 signed long                    Right1Value;
  1520.                 FastFixedType                Wave0Temp;
  1521.  
  1522.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1523.                     >> (32 - FASTFIXEDPRECISION);
  1524.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1525.                     & LocalSamplePositionMask;
  1526.                 /* L+F(R-L) -- applied twice */
  1527.                 Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
  1528.                 Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
  1529.                 Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
  1530.                 Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
  1531.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1532.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  1533.                     Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
  1534.                     - Left1Value)) >> 15) - Wave0Temp)) >> 15));
  1535.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1536.                     &LocalWaveTableSamplePositionDifferential);
  1537.                 SampleCount -= 1;
  1538.             }
  1539.  
  1540.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1541.     }
  1542.  
  1543.  
  1544. static void                        Wave_Stereo_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1545.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1546.     {
  1547.         LongLongRec                    LocalWaveTableSamplePosition;
  1548.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1549.         unsigned long                LocalSamplePositionMask;
  1550.         signed char*                WaveData0;
  1551.         signed char*                WaveData1;
  1552.         FastFixedType                Wave0Weight;
  1553.         FastFixedType                LocalLeftLoudness;
  1554.         FastFixedType                LocalRightLoudness;
  1555.  
  1556.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1557.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1558.             "Wave_Stereo_8BitIn_YesTime_YesWave:  wave index out of range"));
  1559.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1560.             {
  1561.                 /* this is done in case the wave table index is at the maximum, in which */
  1562.                 /* case there is no table+1 to interpolate with. */
  1563.                 Wave_Stereo_8BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1564.                 return;
  1565.             }
  1566.         LocalLeftLoudness = State->LeftLoudness;
  1567.         LocalRightLoudness = State->RightLoudness;
  1568.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1569.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1570.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1571.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1572.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1573.             State->WaveTableIndex)]));
  1574.         WaveData0 = (signed char*)(State->WaveTableMatrix[
  1575.             FastFixed2Int(State->WaveTableIndex)]);
  1576.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1577.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1578.             State->WaveTableIndex) + 1]));
  1579.         WaveData1 = (signed char*)(State->WaveTableMatrix[
  1580.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1581.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1582.  
  1583.         while (SampleCount > 0)
  1584.             {
  1585.                 FastFixedType                LeftWeight;
  1586.                 long                                ArraySubscript;
  1587.                 signed long                    Left0Value;
  1588.                 signed long                    Right0Value;
  1589.                 signed long                    Left1Value;
  1590.                 signed long                    Right1Value;
  1591.                 FastFixedType                Wave0Temp;
  1592.  
  1593.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1594.                     >> (32 - FASTFIXEDPRECISION);
  1595.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1596.                     & LocalSamplePositionMask;
  1597.                 /* L+F(R-L) -- applied twice */
  1598.                 Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
  1599.                 Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
  1600.                 Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
  1601.                 Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
  1602.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1603.                 Wave0Temp = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
  1604.                     - Left1Value)) >> 15) - Wave0Temp)) >> 15);
  1605.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,Wave0Temp);
  1606.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,Wave0Temp);
  1607.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1608.                     &LocalWaveTableSamplePositionDifferential);
  1609.                 SampleCount -= 1;
  1610.             }
  1611.  
  1612.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1613.     }
  1614.  
  1615.  
  1616. static void                        Wave_Mono_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1617.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1618.     {
  1619.         LongLongRec                    LocalWaveTableSamplePosition;
  1620.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1621.         unsigned long                LocalSamplePositionMask;
  1622.         signed short*                WaveData0;
  1623.         signed short*                WaveData1;
  1624.         FastFixedType                Wave0Weight;
  1625.         FastFixedType                LocalOverallLoudness;
  1626.  
  1627.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1628.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1629.             "Wave_Mono_16BitIn_YesTime_YesWave:  wave index out of range"));
  1630.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1631.             {
  1632.                 /* this is done in case the wave table index is at the maximum, in which */
  1633.                 /* case there is no table+1 to interpolate with. */
  1634.                 Wave_Mono_16BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1635.                 return;
  1636.             }
  1637.         LocalOverallLoudness = State->OverallLoudness;
  1638.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1639.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1640.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1641.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1642.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1643.             State->WaveTableIndex)]));
  1644.         WaveData0 = (signed short*)(State->WaveTableMatrix[
  1645.             FastFixed2Int(State->WaveTableIndex)]);
  1646.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1647.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1648.             State->WaveTableIndex) + 1]));
  1649.         WaveData1 = (signed short*)(State->WaveTableMatrix[
  1650.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1651.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1652.  
  1653.         while (SampleCount > 0)
  1654.             {
  1655.                 FastFixedType                LeftWeight;
  1656.                 long                                ArraySubscript;
  1657.                 signed long                    Left0Value;
  1658.                 signed long                    Right0Value;
  1659.                 signed long                    Left1Value;
  1660.                 signed long                    Right1Value;
  1661.                 FastFixedType                Wave0Temp;
  1662.  
  1663.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1664.                     >> (32 - FASTFIXEDPRECISION);
  1665.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1666.                     & LocalSamplePositionMask;
  1667.                 /* L+F(R-L) -- applied twice */
  1668.                 Left0Value = WaveData0[ArraySubscript];
  1669.                 Right0Value = WaveData0[ArraySubscript + 1];
  1670.                 Left1Value = WaveData1[ArraySubscript];
  1671.                 Right1Value = WaveData1[ArraySubscript + 1];
  1672.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1673.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  1674.                     Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
  1675.                     - Left1Value)) >> 15) - Wave0Temp)) >> 15));
  1676.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1677.                     &LocalWaveTableSamplePositionDifferential);
  1678.                 SampleCount -= 1;
  1679.             }
  1680.  
  1681.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1682.     }
  1683.  
  1684.  
  1685. static void                        Wave_Stereo_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
  1686.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1687.     {
  1688.         LongLongRec                    LocalWaveTableSamplePosition;
  1689.         LongLongRec                    LocalWaveTableSamplePositionDifferential;
  1690.         unsigned long                LocalSamplePositionMask;
  1691.         signed short*                WaveData0;
  1692.         signed short*                WaveData1;
  1693.         FastFixedType                Wave0Weight;
  1694.         FastFixedType                LocalLeftLoudness;
  1695.         FastFixedType                LocalRightLoudness;
  1696.  
  1697.         ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
  1698.             > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
  1699.             "Wave_Stereo_16BitIn_YesTime_YesWave:  wave index out of range"));
  1700.         if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
  1701.             {
  1702.                 /* this is done in case the wave table index is at the maximum, in which */
  1703.                 /* case there is no table+1 to interpolate with. */
  1704.                 Wave_Stereo_16BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
  1705.                 return;
  1706.             }
  1707.         LocalLeftLoudness = State->LeftLoudness;
  1708.         LocalRightLoudness = State->RightLoudness;
  1709.         LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
  1710.         LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
  1711.         LocalSamplePositionMask = State->FramesPerTable - 1;
  1712.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1713.             State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1714.             State->WaveTableIndex)]));
  1715.         WaveData0 = (signed short*)(State->WaveTableMatrix[
  1716.             FastFixed2Int(State->WaveTableIndex)]);
  1717.         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1718.             State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
  1719.             State->WaveTableIndex) + 1]));
  1720.         WaveData1 = (signed short*)(State->WaveTableMatrix[
  1721.             FastFixed2Int(State->WaveTableIndex) + 1]);
  1722.         Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
  1723.  
  1724.         while (SampleCount > 0)
  1725.             {
  1726.                 FastFixedType                LeftWeight;
  1727.                 long                                ArraySubscript;
  1728.                 signed long                    Left0Value;
  1729.                 signed long                    Right0Value;
  1730.                 signed long                    Left1Value;
  1731.                 signed long                    Right1Value;
  1732.                 FastFixedType                Wave0Temp;
  1733.  
  1734.                 LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
  1735.                     >> (32 - FASTFIXEDPRECISION);
  1736.                 ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
  1737.                     & LocalSamplePositionMask;
  1738.                 /* L+F(R-L) -- applied twice */
  1739.                 Left0Value = WaveData0[ArraySubscript];
  1740.                 Right0Value = WaveData0[ArraySubscript + 1];
  1741.                 Left1Value = WaveData1[ArraySubscript];
  1742.                 Right1Value = WaveData1[ArraySubscript + 1];
  1743.                 Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1744.                 Wave0Temp = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  1745.                     * (Right1Value - Left1Value)) >> 15) - Wave0Temp)) >> 15);
  1746.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,Wave0Temp);
  1747.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,Wave0Temp);
  1748.                 LongLongAdd(&LocalWaveTableSamplePosition,
  1749.                     &LocalWaveTableSamplePositionDifferential);
  1750.                 SampleCount -= 1;
  1751.             }
  1752.  
  1753.         State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
  1754.     }
  1755.  
  1756.  
  1757. static void                        Wave_NoOutput(WaveTableStateRec* State,
  1758.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1759.     {
  1760.     }
  1761.